package rpc

import (
	"cloudops/src/common"
	"cloudops/src/config"
	"cloudops/src/models"
	"cloudops/src/pbms"
	"context"
	"fmt"
	"go.uber.org/zap"
)

// InfoReportServer 定义信息上报的rpc服务短结构体
type InfoReportServer struct {
	pbms.InfoReporterServer
	sc *config.ServerConfig
}

// AgentInfoReport 定义信息上报的rpc服务方法
func (s *InfoReportServer) AgentInfoReport(ctx context.Context, in *pbms.AgentInfoReportRequest) (resp *pbms.AgentInfoReportResponse, err error) {
	s.sc.Logger.Info("收到客户端的上报的请求",
		zap.String("详情", in.String()),
	)
	resp = &pbms.AgentInfoReportResponse{}

	instanceId := in.GetSn()

	if instanceId == "" {
		resp.Status = "failed"
		resp.Msg = "缺乏sn号"
		return
	}

	// 获取ECS虚拟机的系统信息
	reqObj := &models.ResourceEcs{
		OsType:   in.GetOsType(),
		VmType:   2,
		Cpu:      int(in.GetCpu()),
		Memory:   int(in.GetMem()),
		Disk:     int(in.GetDisk()),
		OSName:   in.GetOsName(),
		Hostname: in.GetHostname(),
	}
	reqObj.InstanceName = in.GetHostname()
	reqObj.Env = in.GetEnv()
	reqObj.PrivateIpAddress = []string{in.GetIp()}
	reqObj.IpAddr = in.GetIp()
	reqObj.InstanceId = instanceId
	reqObj.Hash = reqObj.GenHash()

	//  根据instanceId获取ECS信息，
	dbEcs, err := models.GetResourceEcsByInstanceId(instanceId)
	notFound := false
	if err != nil {

		if err.Error() != common.ERR_ECS_NOT_FOUND {
			s.sc.Logger.Error("收到信息上报的请求,获取ECS信息失败",
				zap.Error(err),

				zap.String("详情", in.String()),
			)
			resp.Status = "failed"
			resp.Msg = fmt.Sprintf("收到信息上报的请求,获取ECS信息失败:%s", err.Error())
			return
		} else {
			notFound = true
		}

	}
	s.sc.Logger.Info("收到信息上报的请求,获取ECS信息成功",

		zap.String("详情", in.String()),
		zap.Any("结果是否存在", notFound),
		zap.Any("dbEcs", dbEcs),
	)

	if notFound {
		// 如果是新的实例，那么需要新增
		err = reqObj.CreateOne()
		if err != nil {
			errMsg := "收到信息上报的请求,创建ECS信息失败"
			s.sc.Logger.Error(errMsg,
				zap.Error(err),
				zap.String("详情", in.String()),
			)
			resp.Status = "failed"
			resp.Msg = fmt.Sprintf("%s %s", errMsg, err.Error())
			return
		}

		resp.Status = "successAdd"
		resp.Msg = "新增记录成功"
		return

	}

	// 更新逻辑
	if reqObj.Hash == dbEcs.Hash {
		// 说明信息没有变化
		resp.Status = "noChange"
		resp.Msg = "记录字段没有变化，无需操作"
		return
	}
	//
	reqObj.ID = dbEcs.ID
	err = reqObj.UpdateOne()
	if err != nil {
		errMsg := "收到信息上报的请求,更新ECS信息失败"
		s.sc.Logger.Error(errMsg,
			zap.Error(err),
			zap.String("详情", in.String()),
		)
		resp.Status = "updateFailed"
		resp.Msg = fmt.Sprintf("%s %s", errMsg, err.Error())
		return

	}
	resp.Status = "updateSuccess"
	resp.Msg = "更新字段成功"

	return
}
